package com.lry.util.rest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * 请求数据trim过滤
 *
 * @author ALI
 * @since 2022/11/4
 */
@Slf4j
@Order(1000)
@WebFilter
@Component
public class RequestDataFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
        String contentType = request.getContentType();
        if (contentType == null || !contentType.contains("application/json")) {
            chain.doFilter(request, response);
            return;
        }

        HttpRequestWrapper httpRequestWrapper = new HttpRequestWrapper((HttpServletRequest) request);

        String body = httpRequestWrapper.getBody();
        if (StringUtils.isEmpty(body)) {
            chain.doFilter(request, response);
            return;
        }
        Map<String, Object> params = httpRequestWrapper.getParams();
        Map<String, Object> newParam = trim(params);
        httpRequestWrapper.setParams(newParam);
        chain.doFilter(httpRequestWrapper, response);
    }

    private Map<String, Object> trim(Map<String, Object> params) {
        Map<String, Object> newParam = new HashMap<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof Map) {
                value = trim((Map<String, Object>) value);
            } else if (value instanceof Collection) {
                value = trim((Collection) value);
            } else if (value instanceof String && !StringUtils.isEmpty(value)) {
                value = value.toString().trim();
            }
            newParam.put(entry.getKey(), value);
        }
        return newParam;
    }

    private Object trim(Collection objList) {
        Collection<Object> newParam = new ArrayList<>();
        for (Object value : objList) {
            if (value instanceof Map) {
                value = trim((Map<String, Object>) value);
            } else if (value instanceof Collection) {
                value = trim((Collection) value);
            } else if (value instanceof String && !StringUtils.isEmpty(value)) {
                value = value.toString().trim();
            }
            newParam.add(value);
        }
        return newParam;
    }
}
